package net.gdface.sdk;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.Serializable;

/**
 * 通用矩形定义对象
 * @author guyadong
 */
public class FRect implements Serializable{
	private static final FRect NULL=new FRect();
	
	/**
	 * 判断{@code rect}是否为{@code null}或所有字段为0时返回{@code true}
	 * @param rect
	 */
	public static final boolean isNull(FRect rect){
		return null == rect || rect.isZeroAll();
	}
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int left;
	private int top;
	private int width;
	private int height;

	public FRect() {
		this(0,0,0,0);
	}

	public FRect(int left, int top, int width, int height) {
		this.left = left;
		this.top = top;
		this.width = width;
		this.height = height;
	}

	public int getLeft() {
		return this.left;
	}

	public void setLeft(int left) {
		this.left = left;
	}

	public int getTop() {
		return this.top;
	}

	public void setTop(int top) {
		this.top = top;
	}

	public int getWidth() {
		return this.width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return this.height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	@Override
	public String toString() {
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		toStream(new PrintStream(bo));
		return bo.toString();
	}
	/**
	 * 以文本形式向{@link PrintStream}输出对象内容 
	 * @param stream
	 */
	public void toStream(PrintStream stream) {
		stream.printf("[%d,%d,%d,%d]",this.left,this.top, this.width,this.height);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + height;
		result = prime * result + left;
		result = prime * result + top;
		result = prime * result + width;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof FRect)) {
			return false;
		}
		FRect other = (FRect) obj;
		if (height != other.height) {
			return false;
		}
		if (left != other.left) {
			return false;
		}
		if (top != other.top) {
			return false;
		}
		if (width != other.width) {
			return false;
		}
		return true;
	}
	public boolean isZeroAll(){
		return this.equals(NULL);
	}
	public boolean contains(FRect rectangle) {
		return this.contains(rectangle.left, rectangle.top, rectangle.width, rectangle.height);
	}

	public boolean contains(int n, int n2, int n3, int n4) {
		int n5 = this.width;
		int n6 = this.height;
		if ((n5 | n6 | n3 | n4) < 0) {
			return false;
		}
		int n7 = this.left;
		int n8 = this.top;
		if (n < n7 || n2 < n8) {
			return false;
		}
		n5 += n7;
		if ((n3 += n) <= n ? n5 >= n7 || n3 > n5 : n5 >= n7 && n3 > n5) {
			return false;
		}
		n6 += n8;
		if ((n4 += n2) <= n2 ? n6 >= n8 || n4 > n6 : n6 >= n8 && n4 > n6) {
			return false;
		}
		return true;
	}
	/**
	 * 将指定的矩形对象以中心向外长宽扩展指定的比例
	 * @param imageWidth 图像宽度
	 * @param imageHeight 图像高度
	 * @param ratio 扩展比例(大于0)
	 * @return 扩展后的新矩形对象
	 */
	public final FRect grow(int imageWidth,int imageHeight,float ratio){
		if(ratio <= 0){
			throw new  IllegalArgumentException("INVALID ratio,>0 required");
		}
		int gw = (int) (getWidth()*ratio);
		int gh = (int) (getHeight()*ratio);
		return grow(imageWidth,imageHeight,gw,gh,gw,gh);
	}
	/**
	 * 将矩形{@code frect}对象上下左右扩充指定的像素,如果超出图像尺寸,则以图像尺寸为边界<br>
	 * @param imageWidth 图像尺寸:宽度
	 * @param imageHeight 图像尺寸:高度
	 * @param gleft 左边扩展尺寸
	 * @param gtop 顶边扩展尺寸
	 * @param gright 右边扩展尺寸
	 * @param gbottom 底边扩展尺寸
	 * @return 扩展后的新矩形对象
	 */
	public FRect grow(int imageWidth,int imageHeight,int gleft,int gtop,int gright,int gbottom){
		if(imageWidth<0 || imageHeight < 0 || gleft<0 || gtop <0 || gright <0 || gbottom <0){
			throw new  IllegalArgumentException("INVALID input argument,>=0 required");
		}
		int newLeft = Math.max(getLeft() - gleft, 0);
		int newTop = Math.max(getTop() - gtop, 0);
		int newRight= Math.min(getLeft() + getWidth() + gright, imageWidth);
		int newBottom= Math.min(getTop() + getHeight() + gbottom, imageHeight);
		return new FRect(newLeft,newTop,newRight - newLeft,newBottom - newTop);	
	}
}
